import {ElectronicLockMessageDTO, DispatchDTO} from '@shared/service-proxy/service-proxies';
import {Component, OnInit, Injector} from '@angular/core';
import {AppComponentBase} from '@shared/common/app-component-base';
import {SiteDTO, ElectronicLockDTO, ServiceProxy, UserInfoDTO} from '@shared/service-proxy/service-proxies';
import {loadModules} from 'esri-loader';
import esri = __esri;
import {ElementRef, ViewChild} from "@node_modules/@angular/core";
import {AppConsts} from "@shared/AppConsts";

@Component({
  selector: 'app-road-monitoring-management',
  templateUrl: './road-monitoring-management.component.html',
  styleUrls: ['./road-monitoring-management.component.less']
})
export class RoadMonitoringManagementComponent extends AppComponentBase implements OnInit {
  @ViewChild('mapViewNode') private mapViewEl: ElementRef;

  siteId = '';
  lockState: string = '';
  lockNo: string = '';
  startTime: null;
  endTime: null;
  dateRange = [];
  sites: SiteDTO[];
  states = [];
  locks: ElectronicLockDTO[] = [];
  tempLocks: ElectronicLockDTO[];
  pathPoins: Array<any> = [];
  currentUser = this.appSession.user;
  sitePoints: Array<any> = [];
  lockPoints: Array<any> = [];
  legendShow: boolean = false;
  mapModules: Array<any> = [];
  mapView: esri.MapView;

  constructor(
    injector: Injector,
    private _service: ServiceProxy) {
    super(injector);
  }


  ngOnInit() {
    this.getSites();
    this.getLockStates();
    this.getLocks();
    this.setMapView();
    $(window).resize(() => {
      this.setMapView();
    });
  }

  setMapView() {
    const $mapview = $('.esri-view');
    $mapview.height($(window).innerHeight() - 240);
  }

  setLocks(siteId?: string) {
    //site 站点
    this.lockPoints = [];
    this._service.getListElectronicLockAndMessageUsingGET(siteId).subscribe(result => {
      this.lockPoints = result.result.fieldList.filter(m => m.electronicLockMessageDTO != null && m.electronicLockMessageDTO.latitude != 0);
      console.log(this.lockPoints)
      this.initializeMap();
    })
  }

  getSites() {
    this._service.getAllSitesBySiteUsingGET().subscribe(result => {
      this.sites = result.result.fieldList;
      this.sites.map(m => {
        this.sitePoints.push([m.lng, m.lat]);
      });
      if (this.currentUser.siteId) {
        this.siteId = this.currentUser.siteId;
        this.setLocks(this.sites[0].id);
      } else {
        this.setLocks();
      }

    })
  }

  getLockStates() {
    this._service.getDictionaryByDictionaryTypeUsingGET('electronicLock_state').subscribe(result => {
      this.states = result.result.fieldList;
    })
  }

  getLocks() {
    this._service.getAllElectronicLocksUsingGET().subscribe(result => {
      this.locks = result.result.fieldList;
      this.tempLocks = this.locks;
    });
  }

  changeState() {
    if (this.lockState)
      this.tempLocks = this.locks.filter(m => m.state == this.lockState);
    else
      this.tempLocks = this.locks;
  }

  onChange(result: any): void {
    if (result) {
      this.startTime = result[0];
      this.endTime = result[1];
    }
  }


  reset() {
    this.siteId = '';
    this.lockState = '';
    this.lockNo = '';
  }


  getRouteByParams() {
    this.pathPoins = [];
    this._service.searchRoutesByCondUsingGET(1, 20000, this.siteId, this.lockNo, this.lockState, this.startTime, this.endTime).subscribe(result => {

      result.result.fieldList.map(m => {
        if (parseInt(m.longitude) != 0 && parseInt(m.latitude) != 0)
          this.pathPoins.push([m.longitude, m.latitude]);
      });
      if (this.pathPoins.length != 0) {
        this._center = this.pathPoins[0];
      }

      this.initializeMap();

    })
  }

  drawTrajectory() {
    const [
      Map,
      MapView,
      ScaleBar,
      Graphic] = this.mapModules;
    const trajectoryMarkerSymbol = {
      type: "picture-marker",  // autocasts as new PictureMarkerSymbol()
      url: "/assets/images/icon-car.png",
      width: "25px",
      height: "25px",
      yoffset: "12px"
    };
    let i = 0;
    let trajectoryPointGraphicOld;
    const timer = setInterval(() => {
      if (i < this.pathPoins.length) {
        this.mapView.graphics.remove(trajectoryPointGraphicOld);
        const trajectoryPointGraphic = new Graphic({
          geometry: {
            type: "point",  // autocasts as new Point()
            longitude: this.pathPoins[i][0],
            latitude: this.pathPoins[i][1]
          },
          symbol: trajectoryMarkerSymbol
        });

        this.mapView.graphics.add(trajectoryPointGraphic);
        trajectoryPointGraphicOld = trajectoryPointGraphic;
        i++;
      } else {
        clearInterval(timer);
      }

    }, 500);


  }

  async initializeMap() {
    try {
      const [
        Map,
        MapView,
        ScaleBar,
        TileLayer,
        Graphic] = this.mapModules = await loadModules([
        'esri/Map',
        'esri/views/MapView',
        'esri/widgets/ScaleBar',
        'esri/layers/TileLayer',
        'esri/Graphic',
        'dojo/domReady!'
      ], {
        url: AppConsts.arcgisMapUrl, css: AppConsts.arcgisStyleUrl
      });


      this.mapView = new MapView({
        container: this.mapViewEl.nativeElement,
        center: this._center,
        zoom: this._zoom,
        map: new Map({
          // basemap: this._basemap,
          layers: new TileLayer({
            url: AppConsts.arcgisMapServerUrl
          })
        })
      });

      const scaleBar = new ScaleBar({
        view: this.mapView,
        unit: "dual" // The scale bar displays both metric and non-metric units.
      });
      this.mapView.ui.add(scaleBar, "bottom-left");
      // All resources in the MapView and the map have loaded.
      // Now execute additional processes
      this.mapView.when(() => {
        // First create a line geometry (this is the Keystone pipeline)
        const points = {
          type: "multipoint", // autocasts as new Point()
          points: this.sitePoints
        };
        // Create a symbol for drawing the point
        const markerSymbol = {
          type: "picture-marker",  // autocasts as new PictureMarkerSymbol()
          url: "/assets/images/icon-flag.png",
          width: "24px",
          height: "24px",
          xoffset: "9px",
          yoffset: "10px"
        };


        // Create a graphic and add the geometry and symbol to it
        const pointGraphic = new Graphic({
          geometry: points,
          symbol: markerSymbol
        });

        // Create a symbol for drawing the point
        const lockMarkerSymbol = {
          type: "picture-marker",  // autocasts as new PictureMarkerSymbol()
          url: "/assets/images/icon-location.png",
          width: "25px",
          height: "25px",
          yoffset: "12px"
        };
        if (this.lockPoints.length) {
          const lockPointGraphic: Array<any> = [];
          this.lockPoints.map((value, index, array) => {
            if (!value.dispatchDTO) {
              value.dispatchDTO = new DispatchDTO();
            }
            if (!value.electronicLockMessageDTO) {
              value.electronicLockMessageDTO = new ElectronicLockMessageDTO();
            }
            const dispathch = {
              containerCode: value.dispatchDTO.containerCode,
              lockCode: value.dispatchDTO.lockCode,
              containerStatusName: value.dispatchDTO.containerStatusName,
              routeCode: value.dispatchDTO.routeCode,
              launchsiteName: value.dispatchDTO.launchsiteName,
              destinationsiteName: value.dispatchDTO.destinationsiteName,
              platenumber: value.dispatchDTO.platenumber,
              latitude: value.electronicLockMessageDTO.latitude,
              longitude: value.electronicLockMessageDTO.longitude,
              speed: value.electronicLockMessageDTO.speed,
              time: value.electronicLockMessageDTO.time
            };


            lockPointGraphic[index] = new Graphic({
              geometry: {
                type: "point",  // autocasts as new Point()
                longitude: value.electronicLockMessageDTO.longitude,
                latitude: value.electronicLockMessageDTO.latitude
              },
              symbol: lockMarkerSymbol,

              attributes: dispathch,
              popupTemplate: { // autocasts as new PopupTemplate()
                title: "{containerCode}",
                content: [{
                  type: "fields",
                  fieldInfos: [{
                    fieldName: "containerCode",
                    label: this.l("container_no")
                  }, {
                    fieldName: "lockCode",
                    label: this.l("lockset_no")
                  }, {
                    fieldName: "containerStatusName",
                    label: this.l("lockset_state")
                  }, {
                    fieldName: "routeCode",
                    label: this.l("path_no")
                  }, {
                    fieldName: "launchsiteName",
                    label: this.l("start_site")
                  }, {
                    fieldName: "destinationsiteName",
                    label: this.l("end_site")
                  }, {
                    fieldName: "platenumber",
                    label: this.l("car_no")
                  }, {
                    fieldName: "longitude",
                    label: this.l("longitude")
                  }, {
                    fieldName: "latitude",
                    label: this.l("latitude")
                  }, {
                    fieldName: "time",
                    label: this.l("get_date")
                  }, {
                    fieldName: "speed",
                    label: this.l("speed")
                  }]
                }]
              }
            });
          });
          this.mapView.graphics.addMany(lockPointGraphic);
        }
        if (this.sitePoints.length) {
          this.mapView.graphics.add(pointGraphic);
        }

        if (this.pathPoins.length) {
          this.mapView.graphics.removeAll();
          const polyline = {
            type: "polyline", // autocasts as new Polyline()
            paths: this.pathPoins
          };

          // Create a symbol for drawing the line
          const lineSymbol = {
            type: "simple-line",
            color: "green",
            width: "4",
            style: "solid"
          };
          const polyLineGraphic = new Graphic({
            geometry: polyline,
            symbol: lineSymbol
          });
          this.mapView.graphics.add(polyLineGraphic);
          this.drawTrajectory();
        }

      });


    } catch (error) {
      console.log('We have an error: ' + error);
    }

  }

}
